use std::any::Any;

// 定义原型特质 `Prototype`，要求实现 `Clone` 和 `Any` 特性。
trait Prototype: Any {
    // 克隆方法，返回一个 `Box<dyn Prototype>`。
    fn clone_box(&self) -> Box<dyn Prototype>;

    // 返回 `Any` 特质的引用，用于类型转换。
    fn as_any(&self) -> &dyn Any;
}

// 具体原型类型 `ConcretePrototype`，实现了 `Clone` 特性和 `Prototype` 特质。
#[derive(Clone)]
struct ConcretePrototype {
    value: i32,
}

impl Prototype for ConcretePrototype {
    // 实现克隆方法，返回克隆后的 `Box<dyn Prototype>`。
    fn clone_box(&self) -> Box<dyn Prototype> {
        Box::new(self.clone())
    }

    // 实现 `as_any()` 方法，返回自身的 `Any` 引用。
    fn as_any(&self) -> &dyn Any {
        self
    }
}

// 主函数入口 `main()`，演示原型模式的使用。
pub fn main() {
    // 创建一个具体原型对象 `ConcretePrototype`。
    let prototype = ConcretePrototype { value: 42 };
    // 克隆原型对象，返回一个 `Box<dyn Prototype>`。
    let cloned_prototype = prototype.clone_box();

    // 尝试从克隆后的原型对象中获取具体类型为 `ConcretePrototype` 的引用。
    if let Some(clone) = cloned_prototype
        .as_any()
        .downcast_ref::<ConcretePrototype>()
    {
        println!("Cloned value: {}", clone.value); // 打印克隆后的具体原型对象的值。
    }
}
